
public class Edge {

    private String id;
    boolean undirected;

    private Vertex from;

    private Vertex to;

    private float weight;
    private float traveltime;
    private float wlutraveltime;

    //variables defined by ricardo for use in sioux falls
    private float freeflowtt;
    private float alpha;
    private float beta;

    private int vehiclesHere;

    public Edge(String id, Vertex from, Vertex to, float weight, boolean undirected,
            float freeflow, float alpha, float beta) {
        this.id = id;
        this.undirected = undirected;

        this.from = from;
        this.from.addOutEdge(this);
        this.to = to;
        this.to.addInEdge(this);

        if (undirected) {
            this.from.addInEdge(this);
            this.to.addOutEdge(this);
        }

        this.weight = weight;
        this.traveltime = weight;
        this.wlutraveltime = weight;
        this.vehiclesHere = 0;

        this.freeflowtt = freeflow;
        this.alpha = alpha;
        this.beta = beta;
    }

    public String getId() {
        return id;
    }

    public Vertex getFrom() {
        return from;
    }

    public Vertex getTo() {
        return to;
    }

    public void setFrom(Vertex from) {
        this.from = from;
    }

    public void setTo(Vertex to) {
        this.to = to;
    }

    public float getWeight() {
        return weight;
    }

    public String toString() {
        return from + ((undirected) ? " -- " : " -> ") + to;
        //return "(" + from + "," + to + ")";
    }

    public boolean isUndirected() {
        return undirected;
    }

    public boolean isDirected() {
        return !undirected;
    }

    public void incVehiclesHere() {
        //synchronized (this) {
        this.vehiclesHere++;
        //}
    }

    public void clearVehiclesHere() {
        this.vehiclesHere = 0;
    }

    public void updateTravelTime() {
        if (Params.ORTUZAR_FUNCTION) {
            this.traveltime = -1 * (this.weight + vehiclesHere * 0.02f);
        } else {
            this.traveltime = -1 * (this.freeflowtt * (1 + this.beta * (float) Math.pow(this.vehiclesHere / this.weight, this.alpha)));
        }
    }

    public float getTravelTime() {
        return this.traveltime;
    }
    
    public float getWLUTravelTime() {
        return (this.vehiclesHere*this.traveltime) - ((this.vehiclesHere-1)*this.wlutraveltime);
    }
    
    public void updateWLUTravelTime(){
        if (Params.ORTUZAR_FUNCTION) {
            this.wlutraveltime = -1 * (this.weight + (this.vehiclesHere-1) * 0.02f);
        } else {
            this.wlutraveltime = -1 * (this.freeflowtt * (1 + this.beta * (float)Math.pow((this.vehiclesHere-1) / this.weight, this.alpha)));
        }
    }

}
